<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .date {
            width: 490px;
            margin: auto;

        }

        p {
            display: flex;
            justify-content: space-between;
        }

        ul {
            width: 490px;
            display: flex;
            margin: auto;
            flex-wrap: wrap;
            padding: 0;
            list-style: none;
        }

        li {
            width: 70px;
            line-height: 50px;
            height: 50px;
            text-align: center;
            background-color: #333;
        }
    </style>
</head>

<body>
    <div class="date">
        <h1 id="showTime"></h1>
        <h3 id="ym"></h3>
        <h4 id="w"></h4>
        <p>
            <span id="prev">&lt;</span>
            <span id="next">&gt;</span>
        </p>
        <ul id="list">

        </ul>
    </div>

    <script>

        // 日历分3部分
        //   本月的天数
        //   上个月的部分天数
        //        经过观察，发现规律  -- 上个月的第一天   上个月的最后一天   本月的第一天是星期几  
        //            发现 日历上显示的上个月的第一天 = 上个月的最后一天 - 本月的第一天是星期几 + 2
        //   下个月的天数


        // 时钟  ---- 永远的读取当前时间
        // 年月  ---- 根据翻页会发生改变   根据全局date
        // 星期  ---- 应该根据当前时间显示   renderWeek 页面一打开就执行了这个函数，后面即使date发生了改变也不会影响w

        // 高亮   当前时间等于 全局date  当前的天数高亮




        var date = new Date();

        // !function() {
            
            // 渲染列表
            renderList();

            // 渲染年月
            renderYearMonth();

            // 渲染星期
            renderWeek();

            // 时钟  --- 每隔1s钟重新获取当前时间
            clock() ;
            setInterval(clock, 1000) ;
        // }()


        // 上翻页
        get('prev').onclick = function() {
            changeDate(0) ;
        //     // 日期推到上个月
        //     date.setDate(0) ;
        //     // 渲染列表
        //     renderList();
        //     // 渲染年月
        //     renderYearMonth();
        }

        // // 下翻页
        get('next').onclick = function() {
            changeDate(32) ;
        //     // 日期推到下个月
        //     date.setDate(32) ;
        //     // 渲染列表
        //     renderList();
        //     // 渲染年月
        //     renderYearMonth();
        }


        function changeDate(n) {
            date.setDate(n) ;
            // 渲染列表
            renderList();
            // 渲染年月
            renderYearMonth();
        }


        function clock() {
            var date = new Date() ;
            var h = date.getHours();
            var m = date.getMinutes();
            var s = date.getSeconds();
            get('showTime').innerHTML = h + ':' + m + ':' + s;
        }




        // 显示星期
        function renderWeek() {
            // var date = new Date()
            var week = ['星期天', '星期一', '星期二', '星期三', '星期四', '星期五'];
            var w = date.getDay();  // 获取星期
            get('w').innerHTML = week[w];
        }




        function renderYearMonth() {
            var y = date.getFullYear();
            var m = date.getMonth() + 1;
            get('ym').innerHTML = y + '-' + m;
        }


        function get(id) {
            return document.getElementById(id)
        }



        // 获取本月的天数   --- 在实现的过程中需要不断的改变日期   使用形参-局部变量  改变的时候不会影响外面的时间
        function getNowDays(t) {
            var date = new Date(t);
            // 日期推到下个月
            date.setDate(32);
            // 推到上个月的第0天 -- 也就是本月的最后一天
            date.setDate(0);
            // 获取本月的最后一天
            var maxDay = date.getDate();
            var arr = [];
            for (var i = 1; i <= maxDay; i++) {
                arr.push(i);
            }
            return arr
        }



        // 求上个月的天数
        function getPrevDays(t) {
            var date = new Date(t);
            // 求本月的第一天是星期几
            date.setDate(1);
            var week = date.getDay();
            // week是星期日的时候，要按照7来算
            week = week > 0 ? week : 7 ;
            // 上个月的最后一天  -- 也就是本月的第0天
            date.setDate(0);
            var maxDay = date.getDate();
            var arr = [];
            // 经过发现的规律，上个月所显示的第一天是 。。。。
            for (var i = maxDay - week + 2; i <= maxDay; i++) {
                arr.push(i);
            }
            return arr
        }




        // 求下个月的天数   42 - 上个月的天数 - 本月的天数
        function getNextDays() {
            var arr = [];
            var prevArrLen = getPrevDays(date).length;
            var nowArrLen = getNowDays(date).length;
            for (var i = 1; i <= 42 - prevArrLen - nowArrLen; i++) {
                arr.push(i);
            }
            return arr
        }





        // 动态生成li
        function renderList() {
            var res = '';
            var prevDaysArr = getPrevDays(date);
            var nowDaysArr = getNowDays(date);
            var nextDaysArr = getNextDays();
            for (var i = 0; i < prevDaysArr.length; i++) {
                res += `<li style="color:gray;">${prevDaysArr[i]}</li>`
            }
            // 当前时间和全局变量的date 时间相同的时候，就显示高亮  -- 年，月，都要相等 ， 天数和数组中的值
            var nowDate = new Date();
            for (var i = 0; i < nowDaysArr.length; i++) {
                if (nowDate.getFullYear() === date.getFullYear() && nowDate.getMonth() === date.getMonth() && nowDate.getDate() === nowDaysArr[i]) {
                    res += `<li style="color:white;background:blue;">${nowDaysArr[i]}</li>`
                } else {
                    res += `<li style="color:white;">${nowDaysArr[i]}</li>`
                }
            }
            for (var i = 0; i < nextDaysArr.length; i++) {
                res += `<li style="color:gray;">${nextDaysArr[i]}</li>`
            }
            // return res ;
            var oUl = document.getElementById('list');
            oUl.innerHTML = res;
        }

    </script>







</body>

</html>